/**
 * <h3>Class description</h3>
 * <h4>日期处理类</h4>
 *
 * <h4>Special Notes</h4>
 * 
 *
 * @ver 0.1
 * @author Vincent
 * 2008-8-11
 */
package com.yict.common.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.TimeZone;

import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.yict.common.Constants;

public class DateUtil extends DateUtils {
	protected static transient final Log log = LogFactory
			.getLog(DateUtil.class);

	private static final int[] dayArray = new int[] { 31, 28, 31, 30, 31, 30,
			31, 31, 30, 31, 30, 31 };

	private static SimpleDateFormat timeStampFormat = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");

	public final static int YEAR = 9;

	public final static int HOUR = 10;

	public final static int DAY = 11;

	public final static int MINUTE = 12;

	public final static int SECOND = 13;

	public final static int MILLISECOND = 14;

	/**
	 * 一天中的天数
	 */
	public static long millionSecondsOfDay = 86400000;

	public static java.sql.Date convertUtilDateT10oSQLDate(java.util.Date date) {
		if (date == null)
			return null;
		Calendar cl = Calendar.getInstance();

		cl.setTime(date);
		java.sql.Date jd = new java.sql.Date(cl.getTimeInMillis());
		return jd;
	}

	public static java.util.Date convertSQLDateToUtilDate(java.sql.Date date) {
		if (date == null)
			return null;
		Calendar cl = Calendar.getInstance();

		cl.setTime(date);
		java.util.Date jd = new java.util.Date(cl.getTimeInMillis());
		return jd;
	}

	public static Date stringToDate(String date) {
		if (date == null || "".equalsIgnoreCase(date))
			return null;

		Calendar cd = Calendar.getInstance();
		StringTokenizer token = new StringTokenizer(date, "-/ :.");
		if (token.hasMoreTokens()) {
			cd.set(Calendar.YEAR, Integer.parseInt(token.nextToken()));
		} else {
			cd.set(Calendar.YEAR, 1970);
		}
		if (token.hasMoreTokens()) {
			cd.set(Calendar.MONTH, Integer.parseInt(token.nextToken()) - 1);
		} else {
			cd.set(Calendar.MONTH, 0);
		}
		if (token.hasMoreTokens()) {
			cd.set(Calendar.DAY_OF_MONTH, Integer.parseInt(token.nextToken()));
		} else {
			cd.set(Calendar.DAY_OF_MONTH, 1);
		}
		if (token.hasMoreTokens()) {
			cd.set(Calendar.HOUR_OF_DAY, Integer.parseInt(token.nextToken()));
		} else {
			cd.set(Calendar.HOUR_OF_DAY, 0);
		}
		if (token.hasMoreTokens()) {
			cd.set(Calendar.MINUTE, Integer.parseInt(token.nextToken()));
		} else {
			cd.set(Calendar.MINUTE, 0);
		}
		if (token.hasMoreTokens()) {
			cd.set(Calendar.SECOND, Integer.parseInt(token.nextToken()));
		} else {
			cd.set(Calendar.SECOND, 0);
		}
		if (token.hasMoreTokens()) {
			cd.set(Calendar.MILLISECOND, Integer.parseInt(token.nextToken()));
		} else {
			cd.set(Calendar.MILLISECOND, 0);
		}

		return cd.getTime();
	}

	public static String dateToString(Date date) {
		if (date == null)
			return "";
		Calendar cl = Calendar.getInstance();
		cl.setTime(date);
		return cl.get(Calendar.YEAR) + "-" + (cl.get(Calendar.MONTH) + 1) + "-"
				+ cl.get(Calendar.DAY_OF_MONTH);
		/*
		 * SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		 * return formatter.format(date).trim();
		 */
	}

	public static String dateTo0String(Date date) {

		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		return formatter.format(date).trim();

	}

	public static Date getFirstDateOfCurrentMonth() {
		Calendar cl = Calendar.getInstance();
		cl.set(Calendar.DAY_OF_MONTH, 1);
		return cl.getTime();
	}

	public static Date getFirstDateOfMonth(String date) {
		return DateUtil.getFirstDateOfMonth(stringToDate(date));
	}
	
	public static Date getFirstDateOfMonth(Date date) {
		Calendar cl = Calendar.getInstance();
		cl.setTime(date);
		cl.set(Calendar.DAY_OF_MONTH, 1);
		return cl.getTime();
	}

	public static Date getLastDateOfMonth(String date) {
		return DateUtil.getLastDateOfMonth(stringToDate(date));
	}

	public static Date getLastDateOfMonth(Date date) {
		Calendar cl = Calendar.getInstance();
		cl.setTime(date);
		int year = cl.get(Calendar.YEAR);
		int month = cl.get(Calendar.MONTH) + 1;
		int day = 0;
		if (month < 1 || month > 12)
			return null;

		if (month == 2) {
			if (isLeapYear(year)) {
				day = 29;
			} else {
				day = dayArray[month - 1];
			}
		} else {
			day = dayArray[month - 1];
		}

		cl.set(Calendar.DAY_OF_MONTH, day);

		return cl.getTime();
	}

	public static boolean isLeapYear(int year) {

		if ((year % 400) == 0)
			return true;
		else if ((year % 4) == 0) {
			if ((year % 100) == 0)
				return false;
			else
				return true;
		} else
			return false;
	}

	/**
	 * 获取当前时间之前的时间 Leo.Li 2007-07-03
	 * 
	 * @param type
	 * @param value
	 * @return
	 */
	public static Date getDateTimeBeforeNow(int type, int value) {
		Calendar cd = Calendar.getInstance();
		long nextTime = cd.getTimeInMillis();

		switch (type) {
		case DAY:
			nextTime = nextTime - 24 * 60 * 60 * 1000 * value;
			break;
		case HOUR:
			nextTime = nextTime - 60 * 60 * 1000 * value;
			break;
		case MINUTE:
			nextTime = nextTime - 60 * 1000 * value;
			break;
		case SECOND:
			nextTime = nextTime - 1000 * value;
			break;
		default:
			break;
		}
		return new Date(nextTime);

	}

	/**
	 * 获取指定时间之前的时间
	 * @author odyssey.tang
	 * @param type
	 * @param value
	 * @return
	 */
	public static Date getDateTimeBefore(Date date, int type, int value) {
		long nextTime = date.getTime();

		switch (type) {
		case DAY:
			nextTime = nextTime - 24 * 60 * 60 * 1000 * value;
			break;
		case HOUR:
			nextTime = nextTime - 60 * 60 * 1000 * value;
			break;
		case MINUTE:
			nextTime = nextTime - 60 * 1000 * value;
			break;
		case SECOND:
			nextTime = nextTime - 1000 * value;
			break;
		default:
			break;
		}
		return new Date(nextTime);

	}

	public static Date getDateTimeAfter(Date date, int type, long value) {
		// Calendar cd = Calendar.getInstance();
		long nextTime = date.getTime();

		switch (type) {
		case DAY:
			nextTime = nextTime + 24 * 60 * 60 * 1000 * value;
			break;
		case HOUR:
			nextTime = nextTime + 60 * 60 * 1000 * value;
			break;
		case MINUTE:
			nextTime = nextTime + 60 * 1000 * value;
			break;
		case SECOND:
			nextTime = nextTime + 1000 * value;
			break;
		case MILLISECOND:
			nextTime = nextTime + value;
			break;
		default:
			break;
		}
		return new Date(nextTime);

	}

	/*
	 * Get the Next Date Write by Jeffy pan 2004-10-21 Date Format:YYYY-MM-DD
	 * YYYY:M:D YYYY/M/DD
	 */
	public static Date getNextDate(String date) {

		Calendar cd = Calendar.getInstance();
		StringTokenizer token = new StringTokenizer(date, "-/ :.");
		if (token.hasMoreTokens()) {
			cd.set(Calendar.YEAR, Integer.parseInt(token.nextToken()));
		} else {
			cd.set(Calendar.YEAR, 1970);
		}
		if (token.hasMoreTokens()) {
			cd.set(Calendar.MONTH, Integer.parseInt(token.nextToken()) - 1);
		} else {
			cd.set(Calendar.MONTH, 0);
		}
		if (token.hasMoreTokens()) {
			cd.set(Calendar.DAY_OF_MONTH, Integer.parseInt(token.nextToken()));
		} else {
			cd.set(Calendar.DAY_OF_MONTH, 1);
		}
		if (token.hasMoreTokens()) {
			cd.set(Calendar.HOUR_OF_DAY, Integer.parseInt(token.nextToken()));
		} else {
			cd.set(Calendar.HOUR_OF_DAY, 0);
		}
		if (token.hasMoreTokens()) {
			cd.set(Calendar.MINUTE, Integer.parseInt(token.nextToken()));
		} else {
			cd.set(Calendar.MINUTE, 0);
		}
		if (token.hasMoreTokens()) {
			cd.set(Calendar.SECOND, Integer.parseInt(token.nextToken()));
		} else {
			cd.set(Calendar.SECOND, 0);
		}
		if (token.hasMoreTokens()) {
			cd.set(Calendar.MILLISECOND, Integer.parseInt(token.nextToken()));
		} else {
			cd.set(Calendar.MILLISECOND, 0);
		}

		long nextTime = cd.getTimeInMillis() + 24 * 60 * 60 * 1000;
		// SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		return new Date(nextTime);
	}

	public static boolean isToday(Date date) {

		Calendar today = Calendar.getInstance();
		today.setTime(new Date());
		Calendar day = Calendar.getInstance();
		day.setTime(date);

		if (today.get(Calendar.YEAR) == day.get(Calendar.YEAR)
				&& today.get(Calendar.MONTH) == day.get(Calendar.MONTH)
				&& today.get(Calendar.DAY_OF_MONTH) == day
						.get(Calendar.DAY_OF_MONTH))
			return true;
		else
			return false;
	}

	public static String formatTimeStamp(Date date) {
		return timeStampFormat.format(date);
	}

	// public static Date parseTimeStamp(String date) throws AWOAException{
	// try {
	// return timeStampFormat.parse(date);
	// } catch (ParseException e) {
	// throw new AWOAException(AWOAException.SYS_ERROR, "日期格式不正确");
	// }
	//
	// }
	public static Date StringToDate(String sDate, int nFormat) {
		Date resDate = new Date();
		try {
			if (sDate == null || sDate.equals(""))
				return null;

			String sFormat = "";

			if (nFormat == 1) {
				sFormat = "yyyy-MM-dd";
			} else if (nFormat == 2) {
				sFormat = "yyyy-MM-dd HH:mm:ss";
			} else if (nFormat == 3) {
				sFormat = "yyyy";
			} else if (nFormat == 4) {
				sFormat = "yyyy-MM-dd HH:mm:ss.S";
			} else if (nFormat == 5) {
				sFormat = "yyyy-MM-dd HH:mm";
			} else if (nFormat == 6) {
				sFormat = "HH:mm";
			} else if (nFormat == 7) {
				sFormat = "MM-dd";
			} else {
				sFormat = "yyyy-MM-dd";
			}

			SimpleDateFormat simDateFormat = new SimpleDateFormat(sFormat);
			resDate = simDateFormat.parse(sDate);
		} catch (Exception e) {
			log.error("", e);
			return null;
		}
		return resDate;
	}

	public static String DateToString(Date dDate, int nFormat) {
		String resString = "";
		// String sDay = "";
		try {
			String sFormat = "";

			if (nFormat == 1) {
				sFormat = "yyyy-MM-dd";
			} else if (nFormat == 2) {
				sFormat = "yyyy-MM-dd HH:mm:ss";
			} else if (nFormat == 3) {
				sFormat = "yyyy-MM-dd EEE";
			} else if (nFormat == 4) {
				sFormat = "yyyy";
			} else if (nFormat == 5) {
				sFormat = "MM-dd";
			} else if (nFormat == 6) {
				sFormat = "yyyy-MM-dd HH:mm:ss.s";
			} else if (nFormat == 7) {
				sFormat = "yyyy-MM-dd HH:mm";
			} else if (nFormat == 8) {
				sFormat = "HH:mm";
			} else if (nFormat == 9) {
				sFormat = "HH:mm:ss";
			} else {
				sFormat = "yyyy-MM-dd";
			}

			SimpleDateFormat simDateFormat = new SimpleDateFormat(sFormat);
			resString = simDateFormat.format(dDate);
		} catch (Exception e) {
			return resString;
		}
		return resString;
	}

	/**
	 * 返回系统当前的完整日期时间 <br>
	 * 格式 1：2008-05-02 13:12:44 <br>
	 * 格式 2：2008/05/02 13:12:44 <br>
	 * 格式 3：2008年5月2日 13:12:44 <br>
	 * 格式 4：2008年5月2日 13时12分44秒 <br>
	 * 格式 5：2008年5月2日 星期五 13:12:44 <br>
	 * 格式 6：2008年5月2日 星期五 13时12分44秒 <br>
	 * 其余格式：2008年5月2日 <br>
	 * 
	 * @param 参数(formatType) :格式代码号
	 * @return 字符串
	 * @author odyssey.tang
	 */
	public static String getChineseFormat(Date dDate, int formatType) {
		SimpleDateFormat sdf = null;
		if (formatType == 1) {
			sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		} else if (formatType == 2) {
			sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		} else if (formatType == 3) {
			sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
		} else if (formatType == 4) {
			sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
		} else if (formatType == 5) {
			sdf = new SimpleDateFormat("yyyy年MM月dd日 E HH:mm:ss");
		} else if (formatType == 6) {
			sdf = new SimpleDateFormat("yyyy年MM月dd日 E HH时mm分ss秒");
		} else {
			sdf = new SimpleDateFormat("yyyy年MM月dd日");
		}
		return sdf.format(dDate);
	}
	
	public static Date parseTimeStamp(String date) throws Exception {
		try {
			return timeStampFormat.parse(date);
		} catch (ParseException e) {
			throw new Exception("日期格式不正确");
		}

	}

	/**
	 * 得到两个日期之间的天数,两头不算,取出数据后，可以根据需要再加
	 * 
	 * @author Vincent
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int getDay(Date date1, Date date2) {
		Long d2 = date2.getTime();
		Long d1 = date1.getTime();
		return (int) ((d2 - d1) / millionSecondsOfDay);
	}

	/**
	 * 根据指定日期格式格式化日期
	 * 
	 * @author Vincent
	 * @param date
	 * @param formater
	 * @return
	 */
	public static String format(Date date, String formater) {
		SimpleDateFormat sdf = new SimpleDateFormat(formater);
		return sdf.format(date);
	}

	/**
	 * 格式化日期
	 * 
	 * @author Vincent
	 * @param date
	 * @param formater
	 * @return
	 */
	public static Date parse(String date, String formater) {
		SimpleDateFormat sdf = new SimpleDateFormat(formater);
		Date result = null;
		try {
			result = sdf.parse(date);
		} catch (ParseException e) {
			log.error("", e);
		}
		return result;
	}

	/**
	 * 根据日期取出是星期几
	 * 
	 * @author Vincent
	 * @param date
	 *            Date
	 * @return int 返回1-7
	 */
	public static int getWeekOfDate(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return (calendar.get(Calendar.DAY_OF_WEEK) - 1) == 0 ? 7 : calendar
				.get(Calendar.DAY_OF_WEEK) - 1;
	}

	/**
	 * format "yyyy-MM-dd HH:mm:ss"
	 */
	public static String dateToString(Date date, String format) {
		if (date == null)
			return null;
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		return formatter.format(date).trim();

	}

	/**
	 * 
	 * @param date
	 * @return
	 * 
	 * @author Solex.Li
	 */
	public static String dateGetTime(Date date) {
		String dateTime = DateToString(date, 2);
		String[] time = dateTime.split(" ");
		if (time.length == 1) {
			return "00:00:00";
		}
		return time[1];
	}

	public static String dateGetTime(String str) {
		String[] time = str.split(" ");
		if (time.length == 1) {
			return "";
		}
		return time[1];
	}

	public static boolean isNull(Date date) {
		if (date == null)
			return true;
		return false;
	}

	public static boolean isNotNull(Date date) {
		return !isNull(date);
	}

	public static Date CSTToGMT(Date date) {
		DateFormat cstFormat = new SimpleDateFormat();
		TimeZone gmtTime = TimeZone.getTimeZone("GMT");
		cstFormat.setTimeZone(gmtTime);
		System.out.println("GMT Time: " + cstFormat.format(date));
		return stringToDate(cstFormat.format(date));
	}

	public static Date GMTToCST(Date date) {
		DateFormat gmtFormat = new SimpleDateFormat();
		TimeZone cstTime = TimeZone.getTimeZone("CST");
		gmtFormat.setTimeZone(cstTime);
		System.out.println("CST Time: " + gmtFormat.format(date));
		return stringToDate(gmtFormat.format(date));
	}

	public static Date getCST(String strGMT) throws ParseException {
		DateFormat df = new SimpleDateFormat("EEE, d-MMM-yyyy HH:mm:ss z",
				Locale.ENGLISH);
		return df.parse(strGMT);
	}

	public static String getGMT(Date dateCST) {
		DateFormat df = new SimpleDateFormat("EEE, d-MMM-yyyy HH:mm:ss z",
				Locale.ENGLISH);
		df.setTimeZone(TimeZone.getTimeZone("GMT")); // modify Time Zone.
		return (df.format(dateCST));
	}

	public static boolean isCurBeforeTime(String timeCode, Date date) {
		boolean bool = false;
		Date dDate = new Date();
		String i = "";
		if (timeCode.equals(Constants.TIME01)) {
			i = DateToString(date, 1) + " 00:00:00.0";
		} else if (timeCode.equals(Constants.TIME02)) {
			i = DateToString(date, 1) + " 08:00:00.0";
		} else if (timeCode.equals(Constants.TIME03)) {
			i = DateToString(date, 1) + " 16:00:00.0";
		}
		if (dDate.before(StringToDate(i, 4))) {
			bool = true;
		}
		return bool;
	}

	/**
	 * 
	 * @param staDate
	 *            被减数(HH:mm)
	 * @param endDate
	 *            减数 (HH:mm)
	 * @return 小时数
	 */
	public static String stringByDate(String staDate, String endDate) {
		String sta1 = staDate.substring(0, staDate.indexOf(":"));
		String sta2 = staDate.substring(staDate.indexOf(":") + 1,
				staDate.length());
		String end1 = endDate.substring(0, staDate.indexOf(":"));
		String end2 = endDate.substring(staDate.indexOf(":") + 1,
				endDate.length());
		int i = Integer.valueOf(sta1) - Integer.valueOf(end1);
		String str = "";
		if (sta2.equals(end2)) {
			str = String.valueOf(i);
		} else if (Integer.valueOf(sta2) > Integer.valueOf(end2)) {
			str = String.valueOf(i);
			str += ".5";
		} else if (Integer.valueOf(end2) > Integer.valueOf(sta2)) {
			str = String.valueOf(i - 1);
			str += ".5";
		}
		return str;
	}
	
	/**
	 * 
	 * @param staDate
	 *            被减数(HH:mm)
	 * @param endDate
	 *            减数 (HH:mm)
	 * @return (HH:mm)
	 */
	public static String stringByDates(String staDate, String endDate) {
		String sta1 = staDate.substring(0, staDate.indexOf(":"));
		String sta2 = staDate.substring(staDate.indexOf(":") + 1,
				staDate.length());
		String end1 = endDate.substring(0, staDate.indexOf(":"));
		String end2 = endDate.substring(staDate.indexOf(":") + 1,
				endDate.length());
		int i = Integer.valueOf(sta1) - Integer.valueOf(end1);
		String str = "";
		if (sta2.equals(end2)) {
			str = String.valueOf(i);
		} else if (Integer.valueOf(sta2) > Integer.valueOf(end2)) {
			str = String.valueOf(i);
			str += ":"+(Integer.valueOf(sta2) - Integer.valueOf(end2));
		} else if (Integer.valueOf(end2) > Integer.valueOf(sta2)) {
			str = String.valueOf(i - 1);
			str += ":"+(60 + Integer.valueOf(sta2) - Integer.valueOf(end2));
		}
		return str;
	}
}
